package net.zjitc.dao;


import net.zjitc.domain.Student;
import net.zjitc.util.JDBCUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: Administrator
 * @Date: 2020-04-27 10:41:10
 * JDBC实现
 */
public class StudentDaoDB implements StudentDao {
    /* 定义3个对象，5个方法里都会用到，所以统一定义在方法的外部
     *  数据库连接对象conn、执行sql语句的对象pstmt、查询返回的结果集rs*/
    private Connection conn = null;
    private PreparedStatement pstmt = null;
    private ResultSet rs = null;

    @Override
    public Student selectByName(String name) {
        /* 查询表中是否存在name的记录，若存在，返回Student对象，若不存在返回null*/
        /* JDBC执行步骤：
         *  1、获取数据库连接
         *  2、定义sql语句
         *  3、获取执行sql的对象
         *  3.1 给占位符？ 赋值
         *  4、执行sql语句 （若是查询，会返回结果集；增删改 会返回int，表示影响了几行）
         *  5、处理返回的结果
         *  6、释放资源 (finally语句中执行)*/
        try {
            conn = JDBCUtils.getConnection();
            /* id是数据库表中的字段名*/
            String sql = "select * from student where name=?";
            pstmt = conn.prepareStatement(sql);
            /* 给？赋值，第一个参数表示第1个问号，第2个参数id表示方法中传入的参数id*/
            pstmt.setString(1, name);
            /* 查询调用executeQuery()，不需要传入参数
             *  增删改调用executeUpdate()*/
            rs = pstmt.executeQuery();
            /*这里rs最多只有一条记录，所以可以用if，若是多条的话，用while*/
            if (rs.next()) {
                /* 方法中的参数 id 是数据库表中的字段名*/
                int id = rs.getInt("id");
                String name1 = rs.getString("name");
                String sex = rs.getString("sex");
                int age = rs.getInt("age");
                Student student = new Student(id, name1, sex, age);
                return student;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(rs, pstmt, conn);
        }
        return null;
    }

    @Override
    public List<Student> selectAll() {
        /* 查询所有信息，并将结果List<Student>返回
           数据库中查询结果保存rs，循环执行，取出每一条记录，封装到Student对象，再加到list集合
        *  */
        ArrayList<Student> list = new ArrayList<Student>();
        try {
            conn = JDBCUtils.getConnection();
            String sql = "select * from student";
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                /* 数据库表中的一行记录，将其封装到Student对象，在添加到集合*/
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String sex = rs.getString("sex");
                int age = rs.getInt("age");
                Student student = new Student(id, name, sex, age);
                list.add(student);
            }
            return list;
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(rs, pstmt, conn);
        }
        return null;
    }

    @Override
    public void insert(Student student) {
        /* 保存之前先判断是否存在该对象，
         其实数据库表中id是主键，是不允许重复的，这里不判断的话，数据库中也会自动保证id不重复 */
        Student s = selectByName(student.getName());
        if (s == null) {
            /*将student对象保存到数据库表中*/
            try {
                conn = JDBCUtils.getConnection();
                /* 这里id也让用户手动添加，所以sql语句的写法不用写明各字段，问号的个数与字段个数一致
                 * 实际表中id是自增的，一般id不会让用户输入，insert语句需要写上插入的字段名:
                 *   insert into student(name,sex,age) values(?,?,?)  */
                String sql = "insert into student(name,sex,age) values(?,?,?)";
                pstmt = conn.prepareStatement(sql);
                pstmt.setString(1, student.getName());
                pstmt.setString(2, student.getSex());
                pstmt.setInt(3, student.getAge());
                int i = pstmt.executeUpdate();
                if (i > 0) {
                    System.out.println("保存成功");
                } else {
                    System.out.println("保存失败！");
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                JDBCUtils.close(pstmt, conn);
            }
        } else {
            System.out.println("保存失败！name重复了！");
        }
    }

    @Override
    public void update(int id, Student student) {
        /* 不需要判断（判断过程已在测试类（界面）操作了 ）
           将id的记录修改为student对象的内容
          */
        try {
            conn = JDBCUtils.getConnection();
            String sql = "update student set name=?,sex=?,age=? where id=?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, student.getName());
            pstmt.setString(2, student.getSex());
            pstmt.setInt(3, student.getAge());
            pstmt.setInt(4, student.getId());
            int i = pstmt.executeUpdate();
            if (i > 0) {
                System.out.println("更新成功");
            } else {
                System.out.println("更新失败");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(pstmt, conn);
        }
    }

    @Override
    public void delete(int id) {
        try {
            conn = JDBCUtils.getConnection();
            String sql = "delete from student where id=?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, id);
            int i = pstmt.executeUpdate();
            if (i > 0) {
                System.out.println("删除成功");
            } else {
                System.out.println("删除失败");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(pstmt, conn);
        }
    }
}
